<template>
  <div class="dashboard-container">
    <div
      v-if="loadingPre"
      v-loading="loadingPre"
      element-loading-text="loading..."
      class="loading-spinner"
    >
    </div>
    <el-tabs v-else v-model="activeTab" v-loading="loading" type="border-card" @tab-click="handleTabClick">
      <el-tab-pane
        v-for="tab in tabs"
        :key="tab.name"
        :label="tab.label"
        :name="tab.name"
      >
        <transition name="fade" mode="out-in">
          <keep-alive>
            <component :is="tab.component" v-show="activeTab === tab.name" :ref="tab.name" />
          </keep-alive>
        </transition>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

// Lazy load components
const Ethernet = () => import(/* webpackPreload: true */ '@/views/ethernet/index.vue')
const Uart2Uart = () => import(/* webpackPreload: true */ '@/views/uart2uart/index.vue')
const Uart2Udp = () => import(/* webpackPreload: true */ '@/views/uart2udp/index.vue')
const Udp2Uart = () => import(/* webpackPreload: true */ '@/views/udp2uart/index.vue')
const UartConfig = () => import(/* webpackPreload: true */ '@/views/uartConfig/index.vue')

export default {
  name: 'Dashboard',
  components: {
    Ethernet,
    Uart2Uart,
    Uart2Udp,
    Udp2Uart,
    UartConfig
  },
  data() {
    return {
      activeTab: 'ethernet',
      loading: false,
      loadingPre: true,
      uart2uartRes: null,
      tabs: [
        { label: '以太网接口', name: 'ethernet', component: Ethernet },
        { label: '串口配置', name: 'uartConfig', component: UartConfig },
        { label: '串口转串口', name: 'uart2uart', component: Uart2Uart },
        { label: '串口转以太网', name: 'uart2udp', component: Uart2Udp },
        { label: '以太网转串口', name: 'udp2uart', component: Udp2Uart }
      ]
    }
  },
  computed: {
    ...mapGetters(['SysCfgInfo'])
  },
  created() {
    setTimeout(() => {
      this.loadingPre = false
    }, 25)

    this.getSysCfg()
    this.$bus.$on('saveClicked', this.handleSaveClicked)
    this.$bus.$on('loadClicked', this.handleLoadClicked)
    this.$bus.$on('exportDataClicked', this.handleExportDataClicked)
    this.$bus.$on('getSettingsClicked', this.handlegetSettingsClicked)
    this.$bus.$on('applyRebootClicked', this.handleApplyRebootClicked)
  },
  beforeDestroy() {
    this.$bus.$off('saveClicked', this.handleSaveClicked)
    this.$bus.$off('loadClicked', this.handleLoadClicked)
    this.$bus.$off('exportDataClicked', this.handleExportDataClicked)
    this.$bus.$off('getSettingsClicked', this.handlegetSettingsClicked)
    this.$bus.$off('applyRebootClicked', this.handleApplyRebootClicked)
  },
  methods: {
    handleTabClick(tab) {
      // console.log(this.activeTab)
    },
    getSysCfg(flag = 0) {
      this.loading = true
      this.$store.dispatch('device/getSysCfg').then(res => {
        this.loading = false
        const {
          eth = [],
          notice = {},
          uart = [],
          uart2uartRule = [],
          uart2udpRule = [],
          udp2uartRule = {}
        } = res
        if (!Object.prototype.hasOwnProperty.call(udp2uartRule, 'udp2uart')) {
          udp2uartRule['udp2uart'] = []
        }

        if (!Object.prototype.hasOwnProperty.call(udp2uartRule, 'multicast')) {
          udp2uartRule['multicast'] = []
        }
        const SysCfgInfo = {
          eth,
          notice,
          uart,
          uart2uartRule,
          uart2udpRule,
          udp2uartRule
        }
        this.$store.commit('device/SET_SYS_CFG', JSON.parse(JSON.stringify(SysCfgInfo)))

        for (const item of this.tabs) {
          this.invokeTabMethod(item.name, 'getSettings') // clear validate
        }
        if (flag === 1) {
          this.$message.success('配置数据获取成功')
        }
      }).catch(() => {
        this.loading = false
      })
    },
    downloadJSON(data, filename = 'master_config.json') {
      // 将 JSON 对象转换为字符串
      const jsonStr = JSON.stringify(data, null, 2)

      // 创建一个 Blob 对象
      const blob = new Blob([jsonStr], { type: 'application/json' })

      // 创建一个 URL 对象
      const url = URL.createObjectURL(blob)

      // 创建一个 <a> 元素
      const a = document.createElement('a')
      a.href = url
      a.download = filename

      // 将 <a> 元素添加到 DOM
      document.body.appendChild(a)

      // 触发下载
      a.click()

      // 移除 <a> 元素
      document.body.removeChild(a)

      // 释放 URL 对象
      URL.revokeObjectURL(url)
    },
    exportData(flag = 0) {
      this.loading = true
      this.$store.dispatch('device/getSysCfg').then(res => {
        this.loading = false

        const SysCfgInfo = {
          eth: res.eth,
          notice: res.notice,
          uart: res.uart,
          uart2uartRule: res.uart2uartRule,
          uart2udpRule: res.uart2udpRule,
          udp2uartRule: res.udp2uartRule
        }

        this.downloadJSON(SysCfgInfo)

        if (flag === 1) {
          this.$message.success('配置文件导出成功')
        }
      }).catch(() => {
        this.loading = false
      })
    },
    setSysCfg(isUpload = false, uploadData = []) {
      this.$store.commit('device/SET_multicast')

      const SysCfgInfo = isUpload
        ? {
          eth: uploadData.eth,
          notice: uploadData.notice,
          uart: uploadData.uart,
          uart2uartRule: uploadData.uart2uartRule,
          uart2udpRule: uploadData.uart2udpRule,
          udp2uartRule: uploadData.udp2uartRule
        }
        : {
          eth: this.SysCfgInfo.eth,
          notice: this.SysCfgInfo.notice,
          uart: this.SysCfgInfo.uart,
          uart2uartRule: this.uart2uartRes,
          uart2udpRule: this.SysCfgInfo.uart2udpRule,
          udp2uartRule: this.SysCfgInfo.udp2uartRule
        }

      const params = JSON.parse(JSON.stringify(SysCfgInfo))
      this.loading = true
      this.$store.dispatch('device/setSysCfg', params).then(res => {
        this.loading = false
        this.getSysCfg()
        this.$message.success('设备配置信息更新成功,等待设备重启...')
      }).catch((err) => {
        console.log(err)
        this.loading = false
      })
    },
    applyAndReboot() {
      this.loading = true
      this.$store.dispatch('device/applyAndReboot').then(res => {
        this.loading = false
        this.$message.success('操作成功，等待设备重启...')
      }).catch((err) => {
        console.log(err)
        this.loading = false
      })
    },
    handleSaveClicked() {
      this.$confirm('是否确认更新设备配置，此操作将重启设备, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        let failCount = 0
        for (const item of this.tabs) {
          if (item.name === 'uart2uart') {
            this.uart2uartRes = await this.invokeTabMethod(item.name, 'save')
            if (!this.uart2uartRes) {
              failCount++
            }
          } else {
            const result = await this.invokeTabMethod(item.name, 'save')
            if (!result) {
              failCount++
            }
          }
        }
        console.log(failCount)
        if (failCount === 0) {
          this.setSysCfg(false, [])
        }
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消操作'
        })
      })
    },
    loadData(res, flag = 0) {
      const {
        eth = [],
        notice = {},
        uart = [],
        uart2uartRule = [],
        uart2udpRule = [],
        udp2uartRule = {}
      } = res

      if (!Object.prototype.hasOwnProperty.call(udp2uartRule, 'udp2uart')) {
        udp2uartRule['udp2uart'] = []
      }

      if (!Object.prototype.hasOwnProperty.call(udp2uartRule, 'multicast')) {
        udp2uartRule['multicast'] = []
      }
      const SysCfgInfo = {
        eth,
        notice,
        uart,
        uart2uartRule,
        uart2udpRule,
        udp2uartRule
      }
      this.$store.commit('device/SET_SYS_CFG', JSON.parse(JSON.stringify(SysCfgInfo)))

      for (const item of this.tabs) {
        this.invokeTabMethod(item.name, 'getSettings') // clear validate
      }
      if (flag === 1) {
        this.$message.success('配置导入成功')
      }
    },
    handleLoadClicked(params) {
      // this.setSysCfg(true, params)
      console.log(params)
      this.loadData(params, 1)
    },
    handleExportDataClicked() {
      this.exportData(1)
    },
    handlegetSettingsClicked() {
      // for (const item of this.tabs) {
      //   this.invokeTabMethod(item.label, 'getSettings') // clear validate
      // }
      this.getSysCfg(1)
    },
    handleApplyRebootClicked() {
      // this.invokeTabMethod(this.activeTab, 'applyReboot')
      this.$confirm('此操作将重启设备, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.applyAndReboot()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消操作'
        })
      })
    },
    async invokeTabMethod(activeTab, methodName) {
      const currentTab = this.$refs[activeTab]
      if (currentTab && currentTab[0] && typeof currentTab[0][methodName] === 'function') {
        const res = await currentTab[0][methodName]()
        return res
      } else {
        console.warn(`Method ${methodName} not found on current tab`)
        return false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.dashboard-container {
  margin: 20px;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}

.fade-enter, .fade-leave-to {
  opacity: 0;
}

.dashboard-header {
  font-size: 20px;
  font-weight: bold;
  color: #333;
}

.device-status-form {
  .el-form-item {
    margin-bottom: 10px;
  }
}

.loading-spinner {
  width: 100%;
  height: 80vh;
}

.el-card {
  margin-bottom: 10px;
}

.equal-height-card {
  display: flex;
  flex-direction: column;
}

.el-form-item {
  margin-bottom: 10px;
}

.button-row {
  text-align: center;
  margin-top: 10px;
}

.statistics-container {
  border: 1px solid #e4e4e4;
  padding: 10px;
}

.statistics-header {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 5px;
}

.status-badge {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
  &.active {
    background-color: green;
  }
}

.dashboard-text {
  font-size: 14px;
  line-height: 40px;
}
</style>
